﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WzhMoveFile
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            //Application.EnableVisualStyles();
            //Application.SetCompatibleTextRenderingDefault(false);

            InitializeComponent();
            // 设置窗体边框样式为 FixedSingle
            this.FormBorderStyle = FormBorderStyle.FixedSingle;
            // 如果不希望有最大化按钮，可以禁用它
            this.MaximizeBox = false;

            ComboRemoveType.Items.Add(new NoDealSameRemove());
            ComboRemoveType.Items.Add(new ABCDealSameRemove());
            ComboRemoveType.Items.Add(new DirNameDealSameRemove());
            ComboRemoveType.Items.Add(new DirName4DealSameRemove());
            ComboRemoveType.Items.Add(new DirNameLineDealSameRemove());
            ComboRemoveType.Items.Add(new ExtendDealSameRemove());
            ComboRemoveType.SelectedValueChanged += ComboRemoveType_SelectedValueChanged;

            ComboRemoveType.SelectedIndex = 0;
        }

        private void ComboRemoveType_SelectedValueChanged(object sender, EventArgs e)
        {
            var removeType = ComboRemoveType.SelectedItem as IRemoveType;
            ExtendInput.Visible = string.IsNullOrEmpty(removeType.defExtend) == false;
            ExtendInput.Text = removeType.defExtend;
        }

        private void StartMove_Click(object sender, EventArgs e)
        {
            string resPath = ResPathInput.Text.Trim();
            resPath = resPath.Replace("\\", "\\\\");
            if (PathTool.DirectoryExists(resPath) == false)
                MessageBox.Show($"resPath:{resPath}    路径不存在！");

            var removeType = ComboRemoveType.SelectedItem as IRemoveType;
            removeType.RomoveTo(resPath, ExtendInput.Text);
        }
    }

    public static class PathTool
    {
        /// <summary>文件夹 是否存在</summary>
        public static bool DirectoryExists(string folderPath)
        {
            if (string.IsNullOrEmpty(folderPath)) return false;
            return Directory.Exists(folderPath);
        }
        public static string[] GetDirectories(string folderPath)
        {
            return Directory.GetDirectories(folderPath, "*", SearchOption.AllDirectories);
        }

        public static string GetDirectorieName(string folderPath)
        {
            if (DirectoryExists(folderPath) == false) return null;
            return Path.GetFileName(folderPath.TrimEnd(Path.DirectorySeparatorChar));
        }

        public static string[] GetFiles(string folderPath,bool isIncludesub)
        {
            if (DirectoryExists(folderPath) == false) return null;
            return Directory.GetFiles(folderPath, "*", isIncludesub ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
        }
        public static string GetFileName(string filesPath)
        {
            return Path.GetFileName(filesPath);
        }
        public static string GetFileNameWithoutExtension(string filesPath)
        {
            return Path.GetFileNameWithoutExtension(filesPath); 
        }
        public static string GetFileExtension(string filesPath)
        {
            return Path.GetExtension(filesPath);
        }
        public static void SameRemoveFiles(string resPath)
        {
            try
            {
                // 获取所有子文件夹
                string[] subDirectories = PathTool.GetDirectories(resPath);
                if (subDirectories == null || subDirectories.Length == 0) return;
                foreach (string subDirectory in subDirectories)
                {
                    // 获取子文件夹中的所有文件
                    string[] files = PathTool.GetFiles(subDirectory, false);
                    foreach (string file in files)
                    {
                        // 获取文件名和扩展名
                        string fileName = PathTool.GetFileNameWithoutExtension(file);
                        string extension = PathTool.GetFileExtension(file);
                        // 设置目标文件路径
                        string destinationFile = Path.Combine(resPath, fileName + extension);
                        int count = 1;
                        // 检查是否有同名文件
                        while (File.Exists(destinationFile))
                        {
                            // 如果有同名文件，重新命名
                            destinationFile = Path.Combine(resPath, $"{fileName} ({count}){extension}");
                            count++;
                        }
                        // 移动文件到目标位置
                        File.Move(file, destinationFile);
                    }
                }

                foreach (string subDirectory in subDirectories)
                {
                    if (PathTool.DirectoryExists(subDirectory) == false) continue;
                    Directory.Delete(subDirectory, true); // true表示递归删除
                }

                MessageBox.Show($"resPath:{resPath}    文件移动完成。");
            }
            catch (Exception ex)
            {
                MessageBox.Show($"resPath:{resPath}  出现错误: { ex.Message}。");
            }
        }

        public static void AddFileNameSub(string resPath, string filenameSub)
        {
            string[] files = PathTool.GetFiles(resPath, false);
            if (files == null) return;
            foreach (string file in files)
            {
                // 获取文件名和扩展名
                string fileName = PathTool.GetFileNameWithoutExtension(file);
                string extension = PathTool.GetFileExtension(file);
                // 设置目标文件路径
                string destinationFile = Path.Combine(resPath, $"{filenameSub}_{fileName}{extension}");
                int count = 1;
                // 检查是否有同名文件
                while (File.Exists(destinationFile))
                {
                    // 如果有同名文件，重新命名
                    destinationFile = Path.Combine(resPath, $"{filenameSub}_{fileName} ({count}){extension}");
                    count++;
                }

                // 移动文件到目标位置
                File.Move(file, destinationFile);
            }
        }

        public static List<string> DealSameName(List<string> nameArray)
        {
            if (nameArray==null|| nameArray.Count==0) return nameArray;

            Dictionary<string, int> occurrenceDict = new Dictionary<string, int>();
            Dictionary<string, int> currentSuffixDict = new Dictionary<string, int>();
            List<string> newDirNameList = new List<string>();

            // 统计每个名称的出现次数
            foreach (string name in nameArray)
                occurrenceDict[name] = occurrenceDict.ContainsKey(name) ? occurrenceDict[name] + 1 : 1;

            // 处理名称列表
            foreach (string name in nameArray)
            {
                // 没有重复，保持原名称
                if (occurrenceDict[name] <= 1) { newDirNameList.Add(name); continue; }
                // 如果有重复，将其转换为带后缀的格式
                if (!currentSuffixDict.ContainsKey(name)) currentSuffixDict[name] = 0;
                // 计算后缀字母
                char suffix = (char)('A' + currentSuffixDict[name]);
                string newName = $"{name}{suffix}";
                newDirNameList.Add(newName);
                // 增加后缀计数
                currentSuffixDict[name]++;
            }
            return newDirNameList;
        }
    }
    public interface IRemoveType
    {
        string defExtend { get; }
        void RomoveTo(string resPath, string extendStr);
    }

    public class NoDealSameRemove : IRemoveType
    {
        public string defExtend { get { return null; } }

        public void RomoveTo(string resPath, string extendStr)
        {
            PathTool.SameRemoveFiles(resPath);
        }
        public override string ToString()
        {
            return "_（123）";
        }
    }
    public class ABCDealSameRemove : IRemoveType
    {
        public string defExtend { get { return null; } }
        public void RomoveTo(string resPath, string extendStr)
        {
            // 获取所有子文件夹
            string[] subDirectories = PathTool.GetDirectories(resPath);
            if (subDirectories == null || subDirectories.Length == 0) return;

            List<string> dirNamelist = new List<string>();
            foreach (string subDirectory in subDirectories)
                dirNamelist.Add("");

            dirNamelist = PathTool.DealSameName(dirNamelist);
            for (int i = 0; i < subDirectories.Length; i++)
                PathTool.AddFileNameSub(subDirectories[i], dirNamelist[i]);

            PathTool.SameRemoveFiles(resPath);
        }
        public override string ToString()
        {
            return "ABC_";
        }
    }

    public class DirNameDealSameRemove : IRemoveType
    {
        public string defExtend { get { return null; } }
        public void RomoveTo(string resPath, string extendStr)
        {
            // 获取所有子文件夹
            string[] subDirectories = PathTool.GetDirectories(resPath);
            if (subDirectories == null || subDirectories.Length == 0) return;

            List<string> dirNamelist = new List<string>();
            foreach (string subDirectory in subDirectories)
                dirNamelist.Add(PathTool.GetDirectorieName(subDirectory));

            dirNamelist = PathTool.DealSameName(dirNamelist);
            for (int i = 0; i < subDirectories.Length; i++)
                PathTool.AddFileNameSub(subDirectories[i], dirNamelist[i]);

            PathTool.SameRemoveFiles(resPath);
        }

        public override string ToString()
        {
            return "夹全名_";
        }
    }
    public class DirName4DealSameRemove : IRemoveType
    {
        public string defExtend { get { return "4"; } }
        public void RomoveTo(string resPath, string extendStr)
        {
            // 获取所有子文件夹
            string[] subDirectories = PathTool.GetDirectories(resPath);
            if (subDirectories == null || subDirectories.Length == 0) return;
            int subLength = 4;
            if (int.TryParse(extendStr, out subLength) == false) subLength = 4;

            List<string> dirNamelist = new List<string>();
            foreach (string subDirectory in subDirectories)
                dirNamelist.Add(PathTool.GetDirectorieName(subDirectory));

            string dirname = null;
            for (int i = 0; i < dirNamelist.Count; i++)
            {
                dirname = dirNamelist[i];
                if (dirname.Length > subLength) dirname = dirname.Substring(0, subLength);
                dirNamelist[i] = dirname;
            }

            dirNamelist = PathTool.DealSameName(dirNamelist);
            for (int i = 0; i < subDirectories.Length; i++)
                PathTool.AddFileNameSub(subDirectories[i], dirNamelist[i]);

            PathTool.SameRemoveFiles(resPath);
        }
        public override string ToString()
        {
            return "夹名4_";
        }
    }
    public class DirNameLineDealSameRemove : IRemoveType
    {
        public string defExtend { get { return "_"; } }
        public void RomoveTo(string resPath, string extendStr)
        {
            // 获取所有子文件夹
            string[] subDirectories = PathTool.GetDirectories(resPath);
            if (subDirectories == null || subDirectories.Length == 0) return;
            string SplitChar = string.IsNullOrEmpty(extendStr) ? defExtend : extendStr;

            List<string> dirNamelist = new List<string>();
            foreach (string subDirectory in subDirectories)
                dirNamelist.Add(PathTool.GetDirectorieName(subDirectory));

            string[] delimiters = new string[] { SplitChar };
            string[] strArray;
            for (int i = 0; i < dirNamelist.Count; i++)
            {
                strArray = dirNamelist[i].Split(delimiters, StringSplitOptions.None);
                dirNamelist[i] = strArray[0];
            }

            dirNamelist = PathTool.DealSameName(dirNamelist);

            for (int i = 0; i < subDirectories.Length; i++)
                PathTool.AddFileNameSub(subDirectories[i], dirNamelist[i]);

            PathTool.SameRemoveFiles(resPath);
        }
        public override string ToString()
        {
            return "夹名$_";
        }
    }

    public class ExtendDealSameRemove : IRemoveType
    {
        public string defExtend { get { return "Null"; } }
        public void RomoveTo(string resPath, string extendStr)
        {
            string[] subDirectories = PathTool.GetDirectories(resPath);
            if (subDirectories == null || subDirectories.Length == 0) return;
            List<string> dirNamelist = new List<string>();
            if (string.IsNullOrEmpty(extendStr) || extendStr == defExtend) extendStr = "";

            foreach (string subDirectory in subDirectories)
                dirNamelist.Add(extendStr);

            dirNamelist = PathTool.DealSameName(dirNamelist);
            for (int i = 0; i < subDirectories.Length; i++)
                PathTool.AddFileNameSub(subDirectories[i], dirNamelist[i]);

            PathTool.SameRemoveFiles(resPath);
        }
        public override string ToString()
        {
            return "扩展_";
        }
    }
}
